package com.unmarshaller.xmlunmarshaller;

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;

import org.apache.log4j.Logger;

import com.unmarshaller.annotation.FilePath;
/**
 * 原型数据解组器
 * @author hongxiao.z
 * @date	2013-10-18
 */
public class XmlUnmarshaller 
{
	public static Logger log = Logger.getLogger(XmlUnmarshaller.class);
	
	/**
	 * 指定类解析
	 * @param clazz
	 * @return
	 * @throws Exception
	 * @date	2013-10-18
	 * @create	hongxiao.z
	 */
	@SuppressWarnings("unchecked")
	public static <T extends Object> T unmarshaller(Class<?> clazz) throws Exception 
	{
		if(clazz == null)
		{
			return null;
		}
		
		/*不存在路径注解*/
		if(!clazz.isAnnotationPresent(FilePath.class))
		{
			StringBuilder sb = new StringBuilder(clazz.getSimpleName()).append(" --- 查找不到对应的数据文件路径！");
			log.warn(sb.toString());
			return null;
		}
		
		/*路径文件格式有错*/
		FilePath pathAnno = clazz.getAnnotation(FilePath.class);
		String path = pathAnno.value();
		/*获取文件后缀名*/
		String suffix = path.substring(path.lastIndexOf("."), path.length());
		
		if(!suffix.equals(".xml"))
		{
			StringBuilder sb = new StringBuilder(clazz.getSimpleName()).append(" --- 无法解析的文件类型！[").append(path).append("]");
			log.warn(sb.toString());
			return null;
		}
		
		log.info(new StringBuilder(path).append(" >>> [").append(clazz.getSimpleName()).append("]").toString());
		
		return (T) unmarshaller(new File(path), clazz);
	}
	
	/**
	 * 解组xml
	 * @param file	文件实体
	 * @return		
	 * @throws Exception
	 * @date	2013-10-18
	 * @create	hongxiao.z
	 */
	private static Object unmarshaller(File file, Class<?> clazz) throws Exception
	{
		JAXBContext context = JAXBContext.newInstance(clazz);
		
		/*创建解组程序工具*/
		Unmarshaller us = context.createUnmarshaller();
		
		/*解组程序, 解组过程中有Unmarshaller.Listener 监听过程。 解组前执行方法beforeUnmarshal, 解组后执行方法afterUnmarshal*/
		return us.unmarshal(file);
		
//		JAXBElement<?> root = us.unmarshal(new StreamSource(new FileInputStream(file)), clazz);   
//		return root.getValue();
	}
}
